-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update mysql #6768
Merged
Merged
Update mysql #6768
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Changes: - docker-library/mysql@5fa3526: Update to 5.7.28-1debian9 - docker-library/mysql@49bedb5: Update to 5.6.46-1debian9 - docker-library/mysql@367788b: Update to 8.0.18-1debian9 - docker-library/mysql@305192d: Merge pull request docker-library/mysql#599 from infosiftr/really_sourced - docker-library/mysql@2501cf3: Improve _is_sourced check - docker-library/mysql@ddf116f: Merge pull request docker-library/mysql#479 from infosiftr/mysql.db-test - docker-library/mysql@0619155: Update "test" database deletion code with extra query from mysql_secure_installation - docker-library/mysql@b5a5d78: Merge pull request docker-library/mysql#471 from ltangvald/refactoring - docker-library/mysql@206541a: Adjust printf to be more resilient; use exit code directly instead of a variable - docker-library/mysql@91785a5: Add --dont-use-mysql-root-password flag for docker_process_sql - docker-library/mysql@8d01eea: Fix source detection for centos, call check_config first, explicit global for DATADIR SOCKET - docker-library/mysql@8a58acb: Adjustments from tianon's comments - docker-library/mysql@169471f: Apply update.sh to update each entrypoint; drop 5.5 from update.sh - docker-library/mysql@06acf82: A few entrypoint updates to increase usability - docker-library/mysql@bbf5d01: Remove empty function docker_wait_for_server - docker-library/mysql@125ac54: Replace function docker_init_client_command with docker_process_sql - docker-library/mysql@964f6c2: Merge function docker_load_tzinfo into docker_setup_db - docker-library/mysql@ce4d14d: Merge function docker_generate_root_password into docker_setup_db - docker-library/mysql@71962c5: Rename function docker_init_database_dir to docker_create_db_directories - docker-library/mysql@04b03e0: Merge functions mysql_write_password_file, docker_init_root_user and docker_setup_db_users into docker_setup_db - docker-library/mysql@880bb34: Rename docker_init_database_user to docker_setup_db_users - docker-library/mysql@dfa4cb4: Rename docker_expire_root_user to mysql_expire_root_user - docker-library/mysql@9b90b1c: Move old-mysql-only logic for waiting for server startup into function - docker-library/mysql@915c792: Rename functions for starting and stopping server - docker-library/mysql@f1abc95: Rename docker_main to _main - docker-library/mysql@c9600d2: Rename log functions from docker to mysql - docker-library/mysql@34ae313: Rename docker_init_env to docker_setup_env - docker-library/mysql@ae7b623: Rename docker_get_config to mysql_get_config - docker-library/mysql@5e10737: Rename docker_write_password_file to mysql_write_password_file - docker-library/mysql@67f2bd3: Rename docker_process_init_file to docker_process_init_files - docker-library/mysql@1503220: Rename docker_verify_env to docker_verify_minimum_env - docker-library/mysql@2fcb086: Rename docker_file_env to file_env - docker-library/mysql@ef9caa9: Rename docker_check_config to mysql_check_config - docker-library/mysql@9f77ea5: entrypoint: Make value checks more consistent - docker-library/mysql@33ba3e5: entrypoint: Only execute main function if the script is not sourced - docker-library/mysql@db2319e: entrypoint: Move main script functionality to function - docker-library/mysql@f9c185f: entrypoint: Move more logic into functions - docker-library/mysql@db12713: entrypoint: Use mktemp instead of install - docker-library/mysql@4672559: Prefix function names in entrypoint with "docker" - docker-library/mysql@eb2821b: Fix typo templaing->templating - docker-library/mysql@2242976: Move flag for password file to when the client command is first defined - docker-library/mysql@03bdbad: Add 5.5 and 5.6 to entrypoint templating - docker-library/mysql@a9e8576: Template: Use --daemonize for temporary server startup. - docker-library/mysql@9e51c81: Template: Use mysqladmin to stop temporary server - docker-library/mysql@ea73775: Template: Store root password in file - docker-library/mysql@a8aa1cf: Template: Create logging functions - docker-library/mysql@34f3ef2: Template: Rename template directory to be hidden - docker-library/mysql@afceb7f: Template: Create functions for starting and stopping server during init - docker-library/mysql@5a727ad: Make template for 5.7+ entrypoint script - docker-library/mysql@f16150e: Unify entrypoint scripts for 5.7 and 8.0 - docker-library/mysql@d56d41d: Update generated README - docker-library/mysql@68f5102: Merge pull request docker-library/mysql#580 from J0WI/https-update - docker-library/mysql@0f33848: Use https in update.sh
docker-library-bot
force-pushed
the
mysql
branch
from
October 14, 2019 04:20
205f234
to
50307fc
Compare
Diff:diff --git a/_bashbrew-list b/_bashbrew-list
index 33aafb0..623187c 100644
--- a/_bashbrew-list
+++ b/_bashbrew-list
@@ -1,9 +1,9 @@
mysql:5
mysql:5.6
-mysql:5.6.45
+mysql:5.6.46
mysql:5.7
-mysql:5.7.27
+mysql:5.7.28
mysql:8
mysql:8.0
-mysql:8.0.17
+mysql:8.0.18
mysql:latest
diff --git a/mysql_5.6/Dockerfile b/mysql_5.6/Dockerfile
index ac00a22..c18aaa2 100644
--- a/mysql_5.6/Dockerfile
+++ b/mysql_5.6/Dockerfile
@@ -44,7 +44,7 @@ RUN set -ex; \
apt-key list > /dev/null
ENV MYSQL_MAJOR 5.6
-ENV MYSQL_VERSION 5.6.45-1debian9
+ENV MYSQL_VERSION 5.6.46-1debian9
RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
diff --git a/mysql_5.6/docker-entrypoint.sh b/mysql_5.6/docker-entrypoint.sh
index 7dbd697..dc6f50a 100755
--- a/mysql_5.6/docker-entrypoint.sh
+++ b/mysql_5.6/docker-entrypoint.sh
@@ -2,21 +2,21 @@
set -eo pipefail
shopt -s nullglob
-# if command starts with an option, prepend mysqld
-if [ "${1:0:1}" = '-' ]; then
- set -- mysqld "$@"
-fi
-
-# skip setup if they want an option that stops mysqld
-wantHelp=
-for arg; do
- case "$arg" in
- -'?'|--help|--print-defaults|-V|--version)
- wantHelp=1
- break
- ;;
- esac
-done
+# logging functions
+mysql_log() {
+ local type="$1"; shift
+ printf '%s [%s] [Entrypoint]: %s\n' "$(date --rfc-3339=seconds)" "$type" "$*"
+}
+mysql_note() {
+ mysql_log Note "$@"
+}
+mysql_warn() {
+ mysql_log Warn "$@" >&2
+}
+mysql_error() {
+ mysql_log ERROR "$@" >&2
+ exit 1
+}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
@@ -27,8 +27,7 @@ file_env() {
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
- echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
- exit 1
+ mysql_error "Both $var and $fileVar are set (but are exclusive)"
fi
local val="$def"
if [ "${!var:-}" ]; then
@@ -40,108 +39,186 @@ file_env() {
unset "$fileVar"
}
-# usage: process_init_file FILENAME MYSQLCOMMAND...
-# ie: process_init_file foo.sh mysql -uroot
-# (process a single initializer file, based on its extension. we define this
-# function here, so that initializer scripts (*.sh) can use the same logic,
-# potentially recursively, or override the logic used in subsequent calls)
-process_init_file() {
- local f="$1"; shift
- local mysql=( "$@" )
+# check to see if this file is being run or sourced from another script
+_is_sourced() {
+ # https://unix.stackexchange.com/a/215279
+ [ "${#FUNCNAME[@]}" -ge 2 ] \
+ && [ "${FUNCNAME[0]}" = '_is_sourced' ] \
+ && [ "${FUNCNAME[1]}" = 'source' ]
+}
+# usage: docker_process_init_files [file [file [...]]]
+# ie: docker_process_init_files /always-initdb.d/*
+# process initializer files, based on file extensions
+docker_process_init_files() {
+ # mysql here for backwards compatibility "${mysql[@]}"
+ mysql=( docker_process_sql )
+
+ echo
+ local f
+ for f; do
case "$f" in
- *.sh) echo "$0: running $f"; . "$f" ;;
- *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
- *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
- *) echo "$0: ignoring $f" ;;
+ *.sh) mysql_note "$0: running $f"; . "$f" ;;
+ *.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
+ *.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
+ *) mysql_warn "$0: ignoring $f" ;;
esac
echo
+ done
}
-_check_config() {
- toRun=( "$@" --verbose --help --log-bin-index="$(mktemp -u)" )
+mysql_check_config() {
+ local toRun=( "$@" --verbose --help ) errors
if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then
- cat >&2 <<-EOM
-
- ERROR: mysqld failed while attempting to check config
- command was: "${toRun[*]}"
-
- $errors
- EOM
- exit 1
+ mysql_error $'mysqld failed while attempting to check config\n\tcommand was: '"${toRun[*]}"$'\n\t'"$errors"
fi
}
# Fetch value from server config
# We use mysqld --verbose --help instead of my_print_defaults because the
# latter only show values present in config files, and not server defaults
-_get_config() {
+mysql_get_config() {
local conf="$1"; shift
- "$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null | awk '$1 == "'"$conf"'" { print $2; exit }'
+ "$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null \
+ | awk -v conf="$conf" '$1 == conf && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
+ # match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)"
}
-# allow the container to be started with `--user`
-if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
- _check_config "$@"
- DATADIR="$(_get_config 'datadir' "$@")"
- mkdir -p "$DATADIR"
- chown -R mysql:mysql "$DATADIR"
- exec gosu mysql "$BASH_SOURCE" "$@"
-fi
+# Do a temporary startup of the MySQL server, for init purposes
+docker_temp_server_start() {
+ if [ "${MYSQL_MAJOR}" = '5.6' ]; then
+ "$@" --skip-networking --socket="${SOCKET}" &
+ mysql_note "Waiting for server startup"
+ local i
+ for i in {30..0}; do
+ # only use the root password if the database has already been initializaed
+ # so that it won't try to fill in a password file when it hasn't been set yet
+ extraArgs=()
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ extraArgs+=( '--dont-use-mysql-root-password' )
+ fi
+ if docker_process_sql "${extraArgs[@]}" --database=mysql <<<'SELECT 1' &> /dev/null; then
+ break
+ fi
+ sleep 1
+ done
+ if [ "$i" = 0 ]; then
+ mysql_error "Unable to start server."
+ fi
+ else
+ # For 5.7+ the server is ready for use as soon as startup command unblocks
+ if ! "$@" --daemonize --skip-networking --socket="${SOCKET}"; then
+ mysql_error "Unable to start server."
+ fi
+ fi
+}
-if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
- # still need to check config, container may have started with --user
- _check_config "$@"
- # Get config
- DATADIR="$(_get_config 'datadir' "$@")"
+# Stop the server. When using a local socket file mysqladmin will block until
+# the shutdown is complete.
+docker_temp_server_stop() {
+ if ! mysqladmin --defaults-extra-file=<( _mysql_passfile ) shutdown -uroot --socket="${SOCKET}"; then
+ mysql_error "Unable to shut down server."
+ fi
+}
- if [ ! -d "$DATADIR/mysql" ]; then
- file_env 'MYSQL_ROOT_PASSWORD'
+# Verify that the minimally required password settings are set for new databases.
+docker_verify_minimum_env() {
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
- echo >&2 'error: database is uninitialized and password option is not specified '
- echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
- exit 1
+ mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
fi
+}
+
+# creates folders for the database
+# also ensures permission for user mysql of run as root
+docker_create_db_directories() {
+ local user; user="$(id -u)"
+ # TODO other directories that are used by default? like /var/lib/mysql-files
+ # see https://github.com/docker-library/mysql/issues/562
mkdir -p "$DATADIR"
- echo 'Initializing database'
- # "Other options are passed to mysqld." (so we pass all "mysqld" arguments directly here)
+ if [ "$user" = "0" ]; then
+ # this will cause less disk access than `chown -R`
+ find "$DATADIR" \! -user mysql -exec chown mysql '{}' +
+ fi
+}
+
+# initializes the database directory
+docker_init_database_dir() {
+ mysql_note "Initializing database files"
+ if [ "$MYSQL_MAJOR" = '5.6' ]; then
mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf "${@:2}"
- echo 'Database initialized'
+ else
+ "$@" --initialize-insecure
+ fi
+ mysql_note "Database files initialized"
- SOCKET="$(_get_config 'socket' "$@")"
- "$@" --skip-networking --socket="${SOCKET}" &
- pid="$!"
+ if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then
+ # https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84
+ mysql_note "Initializing certificates"
+ mysql_ssl_rsa_setup --datadir="$DATADIR"
+ mysql_note "Certificates initialized"
+ fi
+}
- mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
+# Loads various settings that are used elsewhere in the script
+# This should be called after mysql_check_config, but before any other functions
+docker_setup_env() {
+ # Get config
+ declare -g DATADIR SOCKET
+ DATADIR="$(mysql_get_config 'datadir' "$@")"
+ SOCKET="$(mysql_get_config 'socket' "$@")"
- for i in {30..0}; do
- if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
- break
+ # Initialize values that might be stored in a file
+ file_env 'MYSQL_ROOT_HOST' '%'
+ file_env 'MYSQL_DATABASE'
+ file_env 'MYSQL_USER'
+ file_env 'MYSQL_PASSWORD'
+ file_env 'MYSQL_ROOT_PASSWORD'
+
+ declare -g DATABASE_ALREADY_EXISTS
+ if [ -d "$DATADIR/mysql" ]; then
+ DATABASE_ALREADY_EXISTS='true'
fi
- echo 'MySQL init process in progress...'
- sleep 1
- done
- if [ "$i" = 0 ]; then
- echo >&2 'MySQL init process failed.'
- exit 1
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args]
+# ie: docker_process_sql --database=mydb <<<'INSERT ...'
+# ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql
+docker_process_sql() {
+ passfileArgs=()
+ if [ '--dont-use-mysql-root-password' = "$1" ]; then
+ passfileArgs+=( "$1" )
+ shift
+ fi
+ # args sent in can override this db, since they will be later in the command
+ if [ -n "$MYSQL_DATABASE" ]; then
+ set -- --database="$MYSQL_DATABASE" "$@"
fi
+ mysql --defaults-file=<( _mysql_passfile "${passfileArgs[@]}") --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
+}
+
+# Initializes database with timezone info and root password, plus optional extra db/user
+docker_setup_db() {
+ # Load timezone info into database
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
# sed is for https://bugs.mysql.com/bug.php?id=20545
- mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
+ mysql_tzinfo_to_sql /usr/share/zoneinfo \
+ | sed 's/Local time zone must be set--see zic manual page/FCTY/' \
+ | docker_process_sql --dont-use-mysql-root-password --database=mysql
+ # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet
fi
-
- if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
+ # Generate random root password
+ if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
- echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
+ mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
fi
-
- rootCreate=
+ # Sets root password and creates root users for non-localhost hosts
+ local rootCreate=
# default root to listen for connections from anywhere
- file_env 'MYSQL_ROOT_HOST' '%'
- if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
+ if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true
@@ -150,61 +227,143 @@ if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
EOSQL
fi
- "${mysql[@]}" <<-EOSQL
+ local passwordSet=
+ if [ "$MYSQL_MAJOR" = '5.6' ]; then
+ # no, we don't care if read finds a terminating character in this heredoc (see above)
+ read -r -d '' passwordSet <<-EOSQL || true
+ DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
+ SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
+
+ -- 5.5: https://github.com/mysql/mysql-server/blob/e48d775c6f066add457fa8cfb2ebc4d5ff0c7613/scripts/mysql_secure_installation.sh#L192-L210
+ -- 5.6: https://github.com/mysql/mysql-server/blob/06bc670db0c0e45b3ea11409382a5c315961f682/scripts/mysql_secure_installation.sh#L218-L236
+ -- 5.7: https://github.com/mysql/mysql-server/blob/913071c0b16cc03e703308250d795bc381627e37/client/mysql_secure_installation.cc#L792-L818
+ -- 8.0: https://github.com/mysql/mysql-server/blob/b93c1661d689c8b7decc7563ba15f6ed140a4eb6/client/mysql_secure_installation.cc#L726-L749
+ DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%' ;
+ -- https://github.com/docker-library/mysql/pull/479#issuecomment-414561272 ("This is only needed for 5.5 and 5.6")
+ EOSQL
+ else
+ # no, we don't care if read finds a terminating character in this heredoc (see above)
+ read -r -d '' passwordSet <<-EOSQL || true
+ ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
+ EOSQL
+ fi
+
+ # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is just now being set
+ docker_process_sql --dont-use-mysql-root-password --database=mysql <<-EOSQL
-- What's done in this file shouldn't be replicated
-- or products like mysql-fabric won't work
SET @@SESSION.SQL_LOG_BIN=0;
- DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
- SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
+ ${passwordSet}
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
+ FLUSH PRIVILEGES ;
${rootCreate}
DROP DATABASE IF EXISTS test ;
- FLUSH PRIVILEGES ;
EOSQL
- if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
- mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
+ # Creates a custom database and user if specified
+ if [ -n "$MYSQL_DATABASE" ]; then
+ mysql_note "Creating database ${MYSQL_DATABASE}"
+ docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;"
fi
- file_env 'MYSQL_DATABASE'
- if [ "$MYSQL_DATABASE" ]; then
- echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
- mysql+=( "$MYSQL_DATABASE" )
+ if [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ]; then
+ mysql_note "Creating user ${MYSQL_USER}"
+ docker_process_sql --database=mysql <<<"CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;"
+
+ if [ -n "$MYSQL_DATABASE" ]; then
+ mysql_note "Giving user ${MYSQL_USER} access to schema ${MYSQL_DATABASE}"
+ docker_process_sql --database=mysql <<<"GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;"
fi
- file_env 'MYSQL_USER'
- file_env 'MYSQL_PASSWORD'
- if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
- echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[@]}"
+ docker_process_sql --database=mysql <<<"FLUSH PRIVILEGES ;"
+ fi
+}
- if [ "$MYSQL_DATABASE" ]; then
- echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
+_mysql_passfile() {
+ # echo the password to the "file" the client uses
+ # the client command will use process substitution to create a file on the fly
+ # ie: --defaults-file=<( _mysql_passfile )
+ if [ '--dont-use-mysql-root-password' != "$1" ] && [ -n "$MYSQL_ROOT_PASSWORD" ]; then
+ cat <<-EOF
+ [client]
+ password="${MYSQL_ROOT_PASSWORD}"
+ EOF
fi
+}
- echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
+# Mark root user as expired so the password must be changed before anything
+# else can be done (only supported for 5.6+)
+mysql_expire_root_user() {
+ if [ -n "$MYSQL_ONETIME_PASSWORD" ]; then
+ docker_process_sql --database=mysql <<-EOSQL
+ ALTER USER 'root'@'%' PASSWORD EXPIRE;
+ EOSQL
fi
+}
- echo
- ls /docker-entrypoint-initdb.d/ > /dev/null
- for f in /docker-entrypoint-initdb.d/*; do
- process_init_file "$f" "${mysql[@]}"
+# check arguments for an option that would cause mysqld to stop
+# return true if there is one
+_mysql_want_help() {
+ local arg
+ for arg; do
+ case "$arg" in
+ -'?'|--help|--print-defaults|-V|--version)
+ return 0
+ ;;
+ esac
done
+ return 1
+}
- if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
- "${mysql[@]}" <<-EOSQL
- ALTER USER 'root'@'%' PASSWORD EXPIRE;
- EOSQL
+_main() {
+ # if command starts with an option, prepend mysqld
+ if [ "${1:0:1}" = '-' ]; then
+ set -- mysqld "$@"
fi
- if ! kill -s TERM "$pid" || ! wait "$pid"; then
- echo >&2 'MySQL init process failed.'
- exit 1
+
+ # skip setup if they aren't running mysqld or want an option that stops mysqld
+ if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
+ mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
+
+ mysql_check_config "$@"
+ # Load various environment variables
+ docker_setup_env "$@"
+ docker_create_db_directories
+
+ # If container is started as root user, restart as dedicated mysql user
+ if [ "$(id -u)" = "0" ]; then
+ mysql_note "Switching to dedicated user 'mysql'"
+ exec gosu mysql "$BASH_SOURCE" "$@"
fi
+ # there's no database, so it needs to be initialized
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ docker_verify_minimum_env
+ docker_init_database_dir "$@"
+
+ mysql_note "Starting temporary server"
+ docker_temp_server_start "$@"
+ mysql_note "Temporary server started."
+
+ docker_setup_db
+ docker_process_init_files /docker-entrypoint-initdb.d/*
+
+ mysql_expire_root_user
+
+ mysql_note "Stopping temporary server"
+ docker_temp_server_stop
+ mysql_note "Temporary server stopped"
+
echo
- echo 'MySQL init process done. Ready for start up.'
+ mysql_note "MySQL init process done. Ready for start up."
echo
fi
-fi
+ fi
+ exec "$@"
+}
-exec "$@"
+# If we are sourced from elsewhere, don't perform any further actions
+if ! _is_sourced; then
+ _main "$@"
+fi
diff --git a/mysql_5/Dockerfile b/mysql_5/Dockerfile
index b698e6a..b29d750 100644
--- a/mysql_5/Dockerfile
+++ b/mysql_5/Dockerfile
@@ -46,7 +46,7 @@ RUN set -ex; \
apt-key list > /dev/null
ENV MYSQL_MAJOR 5.7
-ENV MYSQL_VERSION 5.7.27-1debian9
+ENV MYSQL_VERSION 5.7.28-1debian9
RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
diff --git a/mysql_5/docker-entrypoint.sh b/mysql_5/docker-entrypoint.sh
index b38c112..dc6f50a 100755
--- a/mysql_5/docker-entrypoint.sh
+++ b/mysql_5/docker-entrypoint.sh
@@ -2,21 +2,21 @@
set -eo pipefail
shopt -s nullglob
-# if command starts with an option, prepend mysqld
-if [ "${1:0:1}" = '-' ]; then
- set -- mysqld "$@"
-fi
-
-# skip setup if they want an option that stops mysqld
-wantHelp=
-for arg; do
- case "$arg" in
- -'?'|--help|--print-defaults|-V|--version)
- wantHelp=1
- break
- ;;
- esac
-done
+# logging functions
+mysql_log() {
+ local type="$1"; shift
+ printf '%s [%s] [Entrypoint]: %s\n' "$(date --rfc-3339=seconds)" "$type" "$*"
+}
+mysql_note() {
+ mysql_log Note "$@"
+}
+mysql_warn() {
+ mysql_log Warn "$@" >&2
+}
+mysql_error() {
+ mysql_log ERROR "$@" >&2
+ exit 1
+}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
@@ -27,8 +27,7 @@ file_env() {
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
- echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
- exit 1
+ mysql_error "Both $var and $fileVar are set (but are exclusive)"
fi
local val="$def"
if [ "${!var:-}" ]; then
@@ -40,114 +39,186 @@ file_env() {
unset "$fileVar"
}
-# usage: process_init_file FILENAME MYSQLCOMMAND...
-# ie: process_init_file foo.sh mysql -uroot
-# (process a single initializer file, based on its extension. we define this
-# function here, so that initializer scripts (*.sh) can use the same logic,
-# potentially recursively, or override the logic used in subsequent calls)
-process_init_file() {
- local f="$1"; shift
- local mysql=( "$@" )
+# check to see if this file is being run or sourced from another script
+_is_sourced() {
+ # https://unix.stackexchange.com/a/215279
+ [ "${#FUNCNAME[@]}" -ge 2 ] \
+ && [ "${FUNCNAME[0]}" = '_is_sourced' ] \
+ && [ "${FUNCNAME[1]}" = 'source' ]
+}
+
+# usage: docker_process_init_files [file [file [...]]]
+# ie: docker_process_init_files /always-initdb.d/*
+# process initializer files, based on file extensions
+docker_process_init_files() {
+ # mysql here for backwards compatibility "${mysql[@]}"
+ mysql=( docker_process_sql )
+ echo
+ local f
+ for f; do
case "$f" in
- *.sh) echo "$0: running $f"; . "$f" ;;
- *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
- *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
- *) echo "$0: ignoring $f" ;;
+ *.sh) mysql_note "$0: running $f"; . "$f" ;;
+ *.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
+ *.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
+ *) mysql_warn "$0: ignoring $f" ;;
esac
echo
+ done
}
-_check_config() {
- toRun=( "$@" --verbose --help )
+mysql_check_config() {
+ local toRun=( "$@" --verbose --help ) errors
if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then
- cat >&2 <<-EOM
-
- ERROR: mysqld failed while attempting to check config
- command was: "${toRun[*]}"
-
- $errors
- EOM
- exit 1
+ mysql_error $'mysqld failed while attempting to check config\n\tcommand was: '"${toRun[*]}"$'\n\t'"$errors"
fi
}
# Fetch value from server config
# We use mysqld --verbose --help instead of my_print_defaults because the
# latter only show values present in config files, and not server defaults
-_get_config() {
+mysql_get_config() {
local conf="$1"; shift
- "$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null | awk '$1 == "'"$conf"'" { print $2; exit }'
+ "$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null \
+ | awk -v conf="$conf" '$1 == conf && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
+ # match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)"
}
-# allow the container to be started with `--user`
-if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
- _check_config "$@"
- DATADIR="$(_get_config 'datadir' "$@")"
- mkdir -p "$DATADIR"
- chown -R mysql:mysql "$DATADIR"
- exec gosu mysql "$BASH_SOURCE" "$@"
-fi
+# Do a temporary startup of the MySQL server, for init purposes
+docker_temp_server_start() {
+ if [ "${MYSQL_MAJOR}" = '5.6' ]; then
+ "$@" --skip-networking --socket="${SOCKET}" &
+ mysql_note "Waiting for server startup"
+ local i
+ for i in {30..0}; do
+ # only use the root password if the database has already been initializaed
+ # so that it won't try to fill in a password file when it hasn't been set yet
+ extraArgs=()
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ extraArgs+=( '--dont-use-mysql-root-password' )
+ fi
+ if docker_process_sql "${extraArgs[@]}" --database=mysql <<<'SELECT 1' &> /dev/null; then
+ break
+ fi
+ sleep 1
+ done
+ if [ "$i" = 0 ]; then
+ mysql_error "Unable to start server."
+ fi
+ else
+ # For 5.7+ the server is ready for use as soon as startup command unblocks
+ if ! "$@" --daemonize --skip-networking --socket="${SOCKET}"; then
+ mysql_error "Unable to start server."
+ fi
+ fi
+}
-if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
- # still need to check config, container may have started with --user
- _check_config "$@"
- # Get config
- DATADIR="$(_get_config 'datadir' "$@")"
+# Stop the server. When using a local socket file mysqladmin will block until
+# the shutdown is complete.
+docker_temp_server_stop() {
+ if ! mysqladmin --defaults-extra-file=<( _mysql_passfile ) shutdown -uroot --socket="${SOCKET}"; then
+ mysql_error "Unable to shut down server."
+ fi
+}
- if [ ! -d "$DATADIR/mysql" ]; then
- file_env 'MYSQL_ROOT_PASSWORD'
+# Verify that the minimally required password settings are set for new databases.
+docker_verify_minimum_env() {
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
- echo >&2 'error: database is uninitialized and password option is not specified '
- echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
- exit 1
+ mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
fi
+}
+# creates folders for the database
+# also ensures permission for user mysql of run as root
+docker_create_db_directories() {
+ local user; user="$(id -u)"
+
+ # TODO other directories that are used by default? like /var/lib/mysql-files
+ # see https://github.com/docker-library/mysql/issues/562
mkdir -p "$DATADIR"
- echo 'Initializing database'
+ if [ "$user" = "0" ]; then
+ # this will cause less disk access than `chown -R`
+ find "$DATADIR" \! -user mysql -exec chown mysql '{}' +
+ fi
+}
+
+# initializes the database directory
+docker_init_database_dir() {
+ mysql_note "Initializing database files"
+ if [ "$MYSQL_MAJOR" = '5.6' ]; then
+ mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf "${@:2}"
+ else
"$@" --initialize-insecure
- echo 'Database initialized'
+ fi
+ mysql_note "Database files initialized"
if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then
# https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84
- echo 'Initializing certificates'
+ mysql_note "Initializing certificates"
mysql_ssl_rsa_setup --datadir="$DATADIR"
- echo 'Certificates initialized'
+ mysql_note "Certificates initialized"
fi
+}
- SOCKET="$(_get_config 'socket' "$@")"
- "$@" --skip-networking --socket="${SOCKET}" &
- pid="$!"
+# Loads various settings that are used elsewhere in the script
+# This should be called after mysql_check_config, but before any other functions
+docker_setup_env() {
+ # Get config
+ declare -g DATADIR SOCKET
+ DATADIR="$(mysql_get_config 'datadir' "$@")"
+ SOCKET="$(mysql_get_config 'socket' "$@")"
- mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
+ # Initialize values that might be stored in a file
+ file_env 'MYSQL_ROOT_HOST' '%'
+ file_env 'MYSQL_DATABASE'
+ file_env 'MYSQL_USER'
+ file_env 'MYSQL_PASSWORD'
+ file_env 'MYSQL_ROOT_PASSWORD'
- for i in {30..0}; do
- if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
- break
+ declare -g DATABASE_ALREADY_EXISTS
+ if [ -d "$DATADIR/mysql" ]; then
+ DATABASE_ALREADY_EXISTS='true'
fi
- echo 'MySQL init process in progress...'
- sleep 1
- done
- if [ "$i" = 0 ]; then
- echo >&2 'MySQL init process failed.'
- exit 1
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args]
+# ie: docker_process_sql --database=mydb <<<'INSERT ...'
+# ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql
+docker_process_sql() {
+ passfileArgs=()
+ if [ '--dont-use-mysql-root-password' = "$1" ]; then
+ passfileArgs+=( "$1" )
+ shift
fi
+ # args sent in can override this db, since they will be later in the command
+ if [ -n "$MYSQL_DATABASE" ]; then
+ set -- --database="$MYSQL_DATABASE" "$@"
+ fi
+
+ mysql --defaults-file=<( _mysql_passfile "${passfileArgs[@]}") --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
+}
+# Initializes database with timezone info and root password, plus optional extra db/user
+docker_setup_db() {
+ # Load timezone info into database
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
# sed is for https://bugs.mysql.com/bug.php?id=20545
- mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
+ mysql_tzinfo_to_sql /usr/share/zoneinfo \
+ | sed 's/Local time zone must be set--see zic manual page/FCTY/' \
+ | docker_process_sql --dont-use-mysql-root-password --database=mysql
+ # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet
fi
-
- if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
+ # Generate random root password
+ if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
- echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
+ mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
fi
-
- rootCreate=
+ # Sets root password and creates root users for non-localhost hosts
+ local rootCreate=
# default root to listen for connections from anywhere
- file_env 'MYSQL_ROOT_HOST' '%'
- if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
+ if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true
@@ -156,60 +227,143 @@ if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
EOSQL
fi
- "${mysql[@]}" <<-EOSQL
+ local passwordSet=
+ if [ "$MYSQL_MAJOR" = '5.6' ]; then
+ # no, we don't care if read finds a terminating character in this heredoc (see above)
+ read -r -d '' passwordSet <<-EOSQL || true
+ DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
+ SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
+
+ -- 5.5: https://github.com/mysql/mysql-server/blob/e48d775c6f066add457fa8cfb2ebc4d5ff0c7613/scripts/mysql_secure_installation.sh#L192-L210
+ -- 5.6: https://github.com/mysql/mysql-server/blob/06bc670db0c0e45b3ea11409382a5c315961f682/scripts/mysql_secure_installation.sh#L218-L236
+ -- 5.7: https://github.com/mysql/mysql-server/blob/913071c0b16cc03e703308250d795bc381627e37/client/mysql_secure_installation.cc#L792-L818
+ -- 8.0: https://github.com/mysql/mysql-server/blob/b93c1661d689c8b7decc7563ba15f6ed140a4eb6/client/mysql_secure_installation.cc#L726-L749
+ DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%' ;
+ -- https://github.com/docker-library/mysql/pull/479#issuecomment-414561272 ("This is only needed for 5.5 and 5.6")
+ EOSQL
+ else
+ # no, we don't care if read finds a terminating character in this heredoc (see above)
+ read -r -d '' passwordSet <<-EOSQL || true
+ ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
+ EOSQL
+ fi
+
+ # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is just now being set
+ docker_process_sql --dont-use-mysql-root-password --database=mysql <<-EOSQL
-- What's done in this file shouldn't be replicated
-- or products like mysql-fabric won't work
SET @@SESSION.SQL_LOG_BIN=0;
- SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
+ ${passwordSet}
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
+ FLUSH PRIVILEGES ;
${rootCreate}
DROP DATABASE IF EXISTS test ;
- FLUSH PRIVILEGES ;
EOSQL
- if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
- mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
+ # Creates a custom database and user if specified
+ if [ -n "$MYSQL_DATABASE" ]; then
+ mysql_note "Creating database ${MYSQL_DATABASE}"
+ docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;"
fi
- file_env 'MYSQL_DATABASE'
- if [ "$MYSQL_DATABASE" ]; then
- echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
- mysql+=( "$MYSQL_DATABASE" )
+ if [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ]; then
+ mysql_note "Creating user ${MYSQL_USER}"
+ docker_process_sql --database=mysql <<<"CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;"
+
+ if [ -n "$MYSQL_DATABASE" ]; then
+ mysql_note "Giving user ${MYSQL_USER} access to schema ${MYSQL_DATABASE}"
+ docker_process_sql --database=mysql <<<"GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;"
fi
- file_env 'MYSQL_USER'
- file_env 'MYSQL_PASSWORD'
- if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
- echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[@]}"
+ docker_process_sql --database=mysql <<<"FLUSH PRIVILEGES ;"
+ fi
+}
- if [ "$MYSQL_DATABASE" ]; then
- echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
+_mysql_passfile() {
+ # echo the password to the "file" the client uses
+ # the client command will use process substitution to create a file on the fly
+ # ie: --defaults-file=<( _mysql_passfile )
+ if [ '--dont-use-mysql-root-password' != "$1" ] && [ -n "$MYSQL_ROOT_PASSWORD" ]; then
+ cat <<-EOF
+ [client]
+ password="${MYSQL_ROOT_PASSWORD}"
+ EOF
fi
+}
- echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
+# Mark root user as expired so the password must be changed before anything
+# else can be done (only supported for 5.6+)
+mysql_expire_root_user() {
+ if [ -n "$MYSQL_ONETIME_PASSWORD" ]; then
+ docker_process_sql --database=mysql <<-EOSQL
+ ALTER USER 'root'@'%' PASSWORD EXPIRE;
+ EOSQL
fi
+}
- echo
- ls /docker-entrypoint-initdb.d/ > /dev/null
- for f in /docker-entrypoint-initdb.d/*; do
- process_init_file "$f" "${mysql[@]}"
+# check arguments for an option that would cause mysqld to stop
+# return true if there is one
+_mysql_want_help() {
+ local arg
+ for arg; do
+ case "$arg" in
+ -'?'|--help|--print-defaults|-V|--version)
+ return 0
+ ;;
+ esac
done
+ return 1
+}
- if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
- "${mysql[@]}" <<-EOSQL
- ALTER USER 'root'@'%' PASSWORD EXPIRE;
- EOSQL
+_main() {
+ # if command starts with an option, prepend mysqld
+ if [ "${1:0:1}" = '-' ]; then
+ set -- mysqld "$@"
fi
- if ! kill -s TERM "$pid" || ! wait "$pid"; then
- echo >&2 'MySQL init process failed.'
- exit 1
+
+ # skip setup if they aren't running mysqld or want an option that stops mysqld
+ if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
+ mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
+
+ mysql_check_config "$@"
+ # Load various environment variables
+ docker_setup_env "$@"
+ docker_create_db_directories
+
+ # If container is started as root user, restart as dedicated mysql user
+ if [ "$(id -u)" = "0" ]; then
+ mysql_note "Switching to dedicated user 'mysql'"
+ exec gosu mysql "$BASH_SOURCE" "$@"
fi
+ # there's no database, so it needs to be initialized
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ docker_verify_minimum_env
+ docker_init_database_dir "$@"
+
+ mysql_note "Starting temporary server"
+ docker_temp_server_start "$@"
+ mysql_note "Temporary server started."
+
+ docker_setup_db
+ docker_process_init_files /docker-entrypoint-initdb.d/*
+
+ mysql_expire_root_user
+
+ mysql_note "Stopping temporary server"
+ docker_temp_server_stop
+ mysql_note "Temporary server stopped"
+
echo
- echo 'MySQL init process done. Ready for start up.'
+ mysql_note "MySQL init process done. Ready for start up."
echo
fi
-fi
+ fi
+ exec "$@"
+}
-exec "$@"
+# If we are sourced from elsewhere, don't perform any further actions
+if ! _is_sourced; then
+ _main "$@"
+fi
diff --git a/mysql_latest/Dockerfile b/mysql_latest/Dockerfile
index c952b98..bb223d9 100644
--- a/mysql_latest/Dockerfile
+++ b/mysql_latest/Dockerfile
@@ -46,7 +46,7 @@ RUN set -ex; \
apt-key list > /dev/null
ENV MYSQL_MAJOR 8.0
-ENV MYSQL_VERSION 8.0.17-1debian9
+ENV MYSQL_VERSION 8.0.18-1debian9
RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
diff --git a/mysql_latest/docker-entrypoint.sh b/mysql_latest/docker-entrypoint.sh
index 720ef6d..dc6f50a 100755
--- a/mysql_latest/docker-entrypoint.sh
+++ b/mysql_latest/docker-entrypoint.sh
@@ -2,21 +2,21 @@
set -eo pipefail
shopt -s nullglob
-# if command starts with an option, prepend mysqld
-if [ "${1:0:1}" = '-' ]; then
- set -- mysqld "$@"
-fi
-
-# skip setup if they want an option that stops mysqld
-wantHelp=
-for arg; do
- case "$arg" in
- -'?'|--help|--print-defaults|-V|--version)
- wantHelp=1
- break
- ;;
- esac
-done
+# logging functions
+mysql_log() {
+ local type="$1"; shift
+ printf '%s [%s] [Entrypoint]: %s\n' "$(date --rfc-3339=seconds)" "$type" "$*"
+}
+mysql_note() {
+ mysql_log Note "$@"
+}
+mysql_warn() {
+ mysql_log Warn "$@" >&2
+}
+mysql_error() {
+ mysql_log ERROR "$@" >&2
+ exit 1
+}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
@@ -27,8 +27,7 @@ file_env() {
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
- echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
- exit 1
+ mysql_error "Both $var and $fileVar are set (but are exclusive)"
fi
local val="$def"
if [ "${!var:-}" ]; then
@@ -40,116 +39,186 @@ file_env() {
unset "$fileVar"
}
-# usage: process_init_file FILENAME MYSQLCOMMAND...
-# ie: process_init_file foo.sh mysql -uroot
-# (process a single initializer file, based on its extension. we define this
-# function here, so that initializer scripts (*.sh) can use the same logic,
-# potentially recursively, or override the logic used in subsequent calls)
-process_init_file() {
- local f="$1"; shift
- local mysql=( "$@" )
+# check to see if this file is being run or sourced from another script
+_is_sourced() {
+ # https://unix.stackexchange.com/a/215279
+ [ "${#FUNCNAME[@]}" -ge 2 ] \
+ && [ "${FUNCNAME[0]}" = '_is_sourced' ] \
+ && [ "${FUNCNAME[1]}" = 'source' ]
+}
+
+# usage: docker_process_init_files [file [file [...]]]
+# ie: docker_process_init_files /always-initdb.d/*
+# process initializer files, based on file extensions
+docker_process_init_files() {
+ # mysql here for backwards compatibility "${mysql[@]}"
+ mysql=( docker_process_sql )
+ echo
+ local f
+ for f; do
case "$f" in
- *.sh) echo "$0: running $f"; . "$f" ;;
- *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
- *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
- *) echo "$0: ignoring $f" ;;
+ *.sh) mysql_note "$0: running $f"; . "$f" ;;
+ *.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
+ *.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
+ *) mysql_warn "$0: ignoring $f" ;;
esac
echo
+ done
}
-_check_config() {
- toRun=( "$@" --verbose --help )
+mysql_check_config() {
+ local toRun=( "$@" --verbose --help ) errors
if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then
- cat >&2 <<-EOM
-
- ERROR: mysqld failed while attempting to check config
- command was: "${toRun[*]}"
-
- $errors
- EOM
- exit 1
+ mysql_error $'mysqld failed while attempting to check config\n\tcommand was: '"${toRun[*]}"$'\n\t'"$errors"
fi
}
# Fetch value from server config
# We use mysqld --verbose --help instead of my_print_defaults because the
# latter only show values present in config files, and not server defaults
-_get_config() {
+mysql_get_config() {
local conf="$1"; shift
"$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null \
- | awk '$1 == "'"$conf"'" && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
+ | awk -v conf="$conf" '$1 == conf && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
# match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)"
}
-# allow the container to be started with `--user`
-if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
- _check_config "$@"
- DATADIR="$(_get_config 'datadir' "$@")"
- mkdir -p "$DATADIR"
- chown -R mysql:mysql "$DATADIR"
- exec gosu mysql "$BASH_SOURCE" "$@"
-fi
+# Do a temporary startup of the MySQL server, for init purposes
+docker_temp_server_start() {
+ if [ "${MYSQL_MAJOR}" = '5.6' ]; then
+ "$@" --skip-networking --socket="${SOCKET}" &
+ mysql_note "Waiting for server startup"
+ local i
+ for i in {30..0}; do
+ # only use the root password if the database has already been initializaed
+ # so that it won't try to fill in a password file when it hasn't been set yet
+ extraArgs=()
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ extraArgs+=( '--dont-use-mysql-root-password' )
+ fi
+ if docker_process_sql "${extraArgs[@]}" --database=mysql <<<'SELECT 1' &> /dev/null; then
+ break
+ fi
+ sleep 1
+ done
+ if [ "$i" = 0 ]; then
+ mysql_error "Unable to start server."
+ fi
+ else
+ # For 5.7+ the server is ready for use as soon as startup command unblocks
+ if ! "$@" --daemonize --skip-networking --socket="${SOCKET}"; then
+ mysql_error "Unable to start server."
+ fi
+ fi
+}
-if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
- # still need to check config, container may have started with --user
- _check_config "$@"
- # Get config
- DATADIR="$(_get_config 'datadir' "$@")"
+# Stop the server. When using a local socket file mysqladmin will block until
+# the shutdown is complete.
+docker_temp_server_stop() {
+ if ! mysqladmin --defaults-extra-file=<( _mysql_passfile ) shutdown -uroot --socket="${SOCKET}"; then
+ mysql_error "Unable to shut down server."
+ fi
+}
- if [ ! -d "$DATADIR/mysql" ]; then
- file_env 'MYSQL_ROOT_PASSWORD'
+# Verify that the minimally required password settings are set for new databases.
+docker_verify_minimum_env() {
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
- echo >&2 'error: database is uninitialized and password option is not specified '
- echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
- exit 1
+ mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
fi
+}
+# creates folders for the database
+# also ensures permission for user mysql of run as root
+docker_create_db_directories() {
+ local user; user="$(id -u)"
+
+ # TODO other directories that are used by default? like /var/lib/mysql-files
+ # see https://github.com/docker-library/mysql/issues/562
mkdir -p "$DATADIR"
- echo 'Initializing database'
+ if [ "$user" = "0" ]; then
+ # this will cause less disk access than `chown -R`
+ find "$DATADIR" \! -user mysql -exec chown mysql '{}' +
+ fi
+}
+
+# initializes the database directory
+docker_init_database_dir() {
+ mysql_note "Initializing database files"
+ if [ "$MYSQL_MAJOR" = '5.6' ]; then
+ mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf "${@:2}"
+ else
"$@" --initialize-insecure
- echo 'Database initialized'
+ fi
+ mysql_note "Database files initialized"
if command -v mysql_ssl_rsa_setup > /dev/null && [ ! -e "$DATADIR/server-key.pem" ]; then
# https://github.com/mysql/mysql-server/blob/23032807537d8dd8ee4ec1c4d40f0633cd4e12f9/packaging/deb-in/extra/mysql-systemd-start#L81-L84
- echo 'Initializing certificates'
+ mysql_note "Initializing certificates"
mysql_ssl_rsa_setup --datadir="$DATADIR"
- echo 'Certificates initialized'
+ mysql_note "Certificates initialized"
fi
+}
- SOCKET="$(_get_config 'socket' "$@")"
- "$@" --skip-networking --socket="${SOCKET}" &
- pid="$!"
+# Loads various settings that are used elsewhere in the script
+# This should be called after mysql_check_config, but before any other functions
+docker_setup_env() {
+ # Get config
+ declare -g DATADIR SOCKET
+ DATADIR="$(mysql_get_config 'datadir' "$@")"
+ SOCKET="$(mysql_get_config 'socket' "$@")"
+
+ # Initialize values that might be stored in a file
+ file_env 'MYSQL_ROOT_HOST' '%'
+ file_env 'MYSQL_DATABASE'
+ file_env 'MYSQL_USER'
+ file_env 'MYSQL_PASSWORD'
+ file_env 'MYSQL_ROOT_PASSWORD'
- mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
+ declare -g DATABASE_ALREADY_EXISTS
+ if [ -d "$DATADIR/mysql" ]; then
+ DATABASE_ALREADY_EXISTS='true'
+ fi
+}
- for i in {30..0}; do
- if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
- break
+# Execute sql script, passed via stdin
+# usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args]
+# ie: docker_process_sql --database=mydb <<<'INSERT ...'
+# ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql
+docker_process_sql() {
+ passfileArgs=()
+ if [ '--dont-use-mysql-root-password' = "$1" ]; then
+ passfileArgs+=( "$1" )
+ shift
fi
- echo 'MySQL init process in progress...'
- sleep 1
- done
- if [ "$i" = 0 ]; then
- echo >&2 'MySQL init process failed.'
- exit 1
+ # args sent in can override this db, since they will be later in the command
+ if [ -n "$MYSQL_DATABASE" ]; then
+ set -- --database="$MYSQL_DATABASE" "$@"
fi
+ mysql --defaults-file=<( _mysql_passfile "${passfileArgs[@]}") --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
+}
+
+# Initializes database with timezone info and root password, plus optional extra db/user
+docker_setup_db() {
+ # Load timezone info into database
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
# sed is for https://bugs.mysql.com/bug.php?id=20545
- mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
+ mysql_tzinfo_to_sql /usr/share/zoneinfo \
+ | sed 's/Local time zone must be set--see zic manual page/FCTY/' \
+ | docker_process_sql --dont-use-mysql-root-password --database=mysql
+ # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet
fi
-
- if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
+ # Generate random root password
+ if [ -n "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
- echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
+ mysql_note "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
fi
-
- rootCreate=
+ # Sets root password and creates root users for non-localhost hosts
+ local rootCreate=
# default root to listen for connections from anywhere
- file_env 'MYSQL_ROOT_HOST' '%'
- if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
+ if [ -n "$MYSQL_ROOT_HOST" ] && [ "$MYSQL_ROOT_HOST" != 'localhost' ]; then
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true
@@ -158,60 +227,143 @@ if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
EOSQL
fi
- "${mysql[@]}" <<-EOSQL
+ local passwordSet=
+ if [ "$MYSQL_MAJOR" = '5.6' ]; then
+ # no, we don't care if read finds a terminating character in this heredoc (see above)
+ read -r -d '' passwordSet <<-EOSQL || true
+ DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
+ SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
+
+ -- 5.5: https://github.com/mysql/mysql-server/blob/e48d775c6f066add457fa8cfb2ebc4d5ff0c7613/scripts/mysql_secure_installation.sh#L192-L210
+ -- 5.6: https://github.com/mysql/mysql-server/blob/06bc670db0c0e45b3ea11409382a5c315961f682/scripts/mysql_secure_installation.sh#L218-L236
+ -- 5.7: https://github.com/mysql/mysql-server/blob/913071c0b16cc03e703308250d795bc381627e37/client/mysql_secure_installation.cc#L792-L818
+ -- 8.0: https://github.com/mysql/mysql-server/blob/b93c1661d689c8b7decc7563ba15f6ed140a4eb6/client/mysql_secure_installation.cc#L726-L749
+ DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%' ;
+ -- https://github.com/docker-library/mysql/pull/479#issuecomment-414561272 ("This is only needed for 5.5 and 5.6")
+ EOSQL
+ else
+ # no, we don't care if read finds a terminating character in this heredoc (see above)
+ read -r -d '' passwordSet <<-EOSQL || true
+ ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
+ EOSQL
+ fi
+
+ # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is just now being set
+ docker_process_sql --dont-use-mysql-root-password --database=mysql <<-EOSQL
-- What's done in this file shouldn't be replicated
-- or products like mysql-fabric won't work
SET @@SESSION.SQL_LOG_BIN=0;
- ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
+ ${passwordSet}
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
+ FLUSH PRIVILEGES ;
${rootCreate}
DROP DATABASE IF EXISTS test ;
- FLUSH PRIVILEGES ;
EOSQL
- if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
- mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
+ # Creates a custom database and user if specified
+ if [ -n "$MYSQL_DATABASE" ]; then
+ mysql_note "Creating database ${MYSQL_DATABASE}"
+ docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;"
fi
- file_env 'MYSQL_DATABASE'
- if [ "$MYSQL_DATABASE" ]; then
- echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
- mysql+=( "$MYSQL_DATABASE" )
+ if [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ]; then
+ mysql_note "Creating user ${MYSQL_USER}"
+ docker_process_sql --database=mysql <<<"CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;"
+
+ if [ -n "$MYSQL_DATABASE" ]; then
+ mysql_note "Giving user ${MYSQL_USER} access to schema ${MYSQL_DATABASE}"
+ docker_process_sql --database=mysql <<<"GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;"
fi
- file_env 'MYSQL_USER'
- file_env 'MYSQL_PASSWORD'
- if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
- echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[@]}"
+ docker_process_sql --database=mysql <<<"FLUSH PRIVILEGES ;"
+ fi
+}
- if [ "$MYSQL_DATABASE" ]; then
- echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
+_mysql_passfile() {
+ # echo the password to the "file" the client uses
+ # the client command will use process substitution to create a file on the fly
+ # ie: --defaults-file=<( _mysql_passfile )
+ if [ '--dont-use-mysql-root-password' != "$1" ] && [ -n "$MYSQL_ROOT_PASSWORD" ]; then
+ cat <<-EOF
+ [client]
+ password="${MYSQL_ROOT_PASSWORD}"
+ EOF
fi
+}
- echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
+# Mark root user as expired so the password must be changed before anything
+# else can be done (only supported for 5.6+)
+mysql_expire_root_user() {
+ if [ -n "$MYSQL_ONETIME_PASSWORD" ]; then
+ docker_process_sql --database=mysql <<-EOSQL
+ ALTER USER 'root'@'%' PASSWORD EXPIRE;
+ EOSQL
fi
+}
- echo
- ls /docker-entrypoint-initdb.d/ > /dev/null
- for f in /docker-entrypoint-initdb.d/*; do
- process_init_file "$f" "${mysql[@]}"
+# check arguments for an option that would cause mysqld to stop
+# return true if there is one
+_mysql_want_help() {
+ local arg
+ for arg; do
+ case "$arg" in
+ -'?'|--help|--print-defaults|-V|--version)
+ return 0
+ ;;
+ esac
done
+ return 1
+}
- if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
- "${mysql[@]}" <<-EOSQL
- ALTER USER 'root'@'%' PASSWORD EXPIRE;
- EOSQL
+_main() {
+ # if command starts with an option, prepend mysqld
+ if [ "${1:0:1}" = '-' ]; then
+ set -- mysqld "$@"
fi
- if ! kill -s TERM "$pid" || ! wait "$pid"; then
- echo >&2 'MySQL init process failed.'
- exit 1
+
+ # skip setup if they aren't running mysqld or want an option that stops mysqld
+ if [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
+ mysql_note "Entrypoint script for MySQL Server ${MYSQL_VERSION} started."
+
+ mysql_check_config "$@"
+ # Load various environment variables
+ docker_setup_env "$@"
+ docker_create_db_directories
+
+ # If container is started as root user, restart as dedicated mysql user
+ if [ "$(id -u)" = "0" ]; then
+ mysql_note "Switching to dedicated user 'mysql'"
+ exec gosu mysql "$BASH_SOURCE" "$@"
fi
+ # there's no database, so it needs to be initialized
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ docker_verify_minimum_env
+ docker_init_database_dir "$@"
+
+ mysql_note "Starting temporary server"
+ docker_temp_server_start "$@"
+ mysql_note "Temporary server started."
+
+ docker_setup_db
+ docker_process_init_files /docker-entrypoint-initdb.d/*
+
+ mysql_expire_root_user
+
+ mysql_note "Stopping temporary server"
+ docker_temp_server_stop
+ mysql_note "Temporary server stopped"
+
echo
- echo 'MySQL init process done. Ready for start up.'
+ mysql_note "MySQL init process done. Ready for start up."
echo
fi
-fi
+ fi
+ exec "$@"
+}
-exec "$@"
+# If we are sourced from elsewhere, don't perform any further actions
+if ! _is_sourced; then
+ _main "$@"
+fi |
Build test of #6768; 50307fc; $ bashbrew build mysql:8.0.18
Using bashbrew/cache:d022b9aab639215160c76938272dc105e1cb318e182975af019b6ea67288c29e (mysql:8.0.18)
Tagging mysql:8.0.18
Tagging mysql:8.0
Tagging mysql:8
Tagging mysql:latest
$ test/run.sh mysql:8.0.18
testing mysql:8.0.18
'utc' [1/7]...passed
'cve-2014--shellshock' [2/7]...passed
'no-hard-coded-passwords' [3/7]...passed
'override-cmd' [4/7]...passed
'mysql-basics' [5/7].......passed
'mysql-initdb' [6/7]......passed
'mysql-log-bin' [7/7]......passed
$ bashbrew build mysql:5.7.28
Using bashbrew/cache:798456ddd65c50ff739abe189d97f079a4d94843d90f36db4be981e3bede506e (mysql:5.7.28)
Tagging mysql:5.7.28
Tagging mysql:5.7
Tagging mysql:5
$ test/run.sh mysql:5.7.28
testing mysql:5.7.28
'utc' [1/7]...passed
'cve-2014--shellshock' [2/7]...passed
'no-hard-coded-passwords' [3/7]...passed
'override-cmd' [4/7]...passed
'mysql-basics' [5/7]......passed
'mysql-initdb' [6/7]......passed
'mysql-log-bin' [7/7]......passed
$ bashbrew build mysql:5.6.46
Using bashbrew/cache:691821e1656d4c47ac3ef256d85889e86cc132035e016aee9aee9334e8396059 (mysql:5.6.46)
Tagging mysql:5.6.46
Tagging mysql:5.6
$ test/run.sh mysql:5.6.46
testing mysql:5.6.46
'utc' [1/7]...passed
'cve-2014--shellshock' [2/7]...passed
'no-hard-coded-passwords' [3/7]...passed
'override-cmd' [4/7]...passed
'mysql-basics' [5/7].......passed
'mysql-initdb' [6/7]......passed
'mysql-log-bin' [7/7].......passed
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Changes: